package com.friend.service.question.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.common.core.domain.TableDataInfo;
import com.common.core.enums.ResultCode;
import com.common.security.exception.ServiceException;
import com.friend.domain.question.Question;
import com.friend.domain.question.dto.QuestionQueryDTO;
import com.friend.domain.question.es.QuestionES;
import com.friend.domain.question.vo.QuestionDetailVO;
import com.friend.domain.question.vo.QuestionVO;
import com.friend.elasticsearch.QuestionRepository;
import com.friend.manager.QuestionCacheManager;
import com.friend.mapper.question.QuestionMapper;
import com.friend.service.question.QuestionService;
import jakarta.annotation.Resource;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import java.util.List;

@Service
public class QuestionServiceImpl implements QuestionService {

    @Resource
    QuestionRepository questionRepository;

    @Resource
    QuestionMapper questionMapper;

    @Resource
    QuestionCacheManager questionCacheManager;

    @Override
    public TableDataInfo list(QuestionQueryDTO questionQueryDTO) {
        //先从ES中获取数据
        Long count=questionRepository.count();
        if(count<=0){
            //如果ES没有数据
            refreshQuestion();
        }
        //获取难度和模糊匹配的匹配词
        Integer difficulty=questionQueryDTO.getDifficulty();
        String keyword=questionQueryDTO.getKeyword();
        //设置Sort和Pageable，方便后面使用
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        Pageable pageable=PageRequest.of(questionQueryDTO.getPageNum()-1,questionQueryDTO.getPageSize(),sort);
        //从ES中获取数据
        Page<QuestionES> questionESPage;
        if(difficulty==null && StrUtil.isEmpty(keyword)){
            //没有设置 难度 和 匹配词
            questionESPage = questionRepository.findAll(pageable);
        }else if(difficulty==null){
            //没有设置 难度 ，但是设置了 匹配词
            questionESPage = questionRepository.findByTitleOrContent(keyword,keyword,pageable);
        }else if(StrUtil.isEmpty(keyword)){
            //没有设置 匹配词 ， 但是设置了 难度
            questionESPage = questionRepository.findQuestionByDifficulty(difficulty,pageable);
        }else{
            //都设置了
            questionESPage = questionRepository.findByTitleOrContentAndDifficulty(keyword,keyword,difficulty,pageable);
        }
        //总共获取多少条数据
        long total = questionESPage.getTotalElements();
        if(total<=0){
            return TableDataInfo.empty();
        }
        List<QuestionES> questionESList = questionESPage.getContent();
        List<QuestionVO> questionVOS = BeanUtil.copyToList(questionESList, QuestionVO.class);
        return TableDataInfo.success(questionVOS,total);
    }

    @Override
    public QuestionDetailVO detail(Long questionId) {
        //从ES中获取该题目详情
        QuestionES questionES = questionRepository.findById(questionId).orElse(null);
        QuestionDetailVO questionDetailVO=new QuestionDetailVO();
        if(questionES!=null){
            //ES中存在数据，直接返回
            BeanUtil.copyProperties(questionES,questionDetailVO);
            return questionDetailVO;
        }
        //从数据库里查询
        Question question = questionMapper.selectById(questionId);
        if(question==null){
            //没有该题目
            throw new ServiceException(ResultCode.FAILED_NOT_EXISTS);
        }

        BeanUtil.copyProperties(question,questionDetailVO);

        //更新ES中的数据
        refreshQuestion();

        return questionDetailVO;
    }

    @Override
    public String preQuestion(Long questionId) {
        Long listSize = questionCacheManager.getListSize();
        if(listSize==null || listSize<=0){
            questionCacheManager.refreshCache();
        }
        return questionCacheManager.preQuestion(questionId).toString();
    }

    @Override
    public String nextQuestion(Long questionId) {
        Long listSize = questionCacheManager.getListSize();
        if(listSize==null || listSize<=0){
            questionCacheManager.refreshCache();
        }
        return questionCacheManager.nextQuestion(questionId).toString();
    }

    private void refreshQuestion() {
        //从MySQL中获取题目列表
        List<Question> questionList=questionMapper.selectList(new LambdaQueryWrapper<Question>());
        //将题目列表转化成ES列表
        List<QuestionES> questionESList = BeanUtil.copyToList(questionList, QuestionES.class);
        //存入ES
        questionRepository.saveAll(questionESList);
    }
}
